package com.kakarote.admin.config.redis;

import com.kakarote.common.log.entity.OperateLogEntity;
import com.kakarote.core.redis.Redis;
import com.kakarote.core.utils.BaseUtil;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @author: admin
 * @version: v1.0
 * @date:2023/10/7
 */
@Component
public class RedisListener implements MessageListener {

    @Autowired
    private Redis redis;
    @Resource
    protected SqlSessionFactory sqlSessionFactory;

    @Autowired
    private RedisMessageListenerContainer listenerContainer;


    @PostConstruct
    public void init() {
        listenerContainer.addMessageListener(this, new ChannelTopic("operateLog"));
    }

    public void saveOperateLog(OperateLogEntity.Entity entity) {
        Connection connection = sqlSessionFactory.openSession().getConnection();
        try {
            String sql = "INSERT INTO wk_operate_log (`id`, `request_uri`, `behavior`, `apply`, `client_ip`, `create_user_id`, `create_time`, `operation_obj`, `operation_info`, `equipment_type`, `type`,`module`) VALUES (?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setLong(1, BaseUtil.getNextId());
            preparedStatement.setString(2, entity.getRequestUri());
            preparedStatement.setInt(3, entity.getBehavior());
            preparedStatement.setInt(4, entity.getApply());
            preparedStatement.setString(5, entity.getClientIp());
            preparedStatement.setLong(6, entity.getCreateUserId());
            preparedStatement.setString(7, entity.getCreateTime());
            preparedStatement.setString(8, entity.getOperationObj());
            preparedStatement.setString(9, entity.getOperationInfo());
            preparedStatement.setString(10, entity.getEquipmentType());
            preparedStatement.setInt(11, entity.getType());
            preparedStatement.setInt(12, entity.getModule());
            preparedStatement.execute();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * Callback for processing received objects through Redis.
     *
     * @param message message must not be {@literal null}.
     * @param pattern pattern matching the channel (if specified) - can be {@literal null}.
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        OperateLogEntity.Entity entity = (OperateLogEntity.Entity) redis.getValueSerializer().deserialize(message.getBody());
        if (entity == null) {
            return;
        }
        saveOperateLog(entity);
    }
}
